home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Risc World 3
/
Risc World 3.iso
/
SOFTWARE
/
ISSUE6
/
PD
/
PDF
/
DrawFile
/
c++
/
GuiDrawFile
< prev
next >
Wrap
Text File
|
2003-02-14
|
7KB
|
236 lines
//--------------------------------------------------------------------------
//
// Copyright (c) 2002, Colin Granville
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or
// without modification, are permitted provided that the following
// conditions are met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials
// provided with the distribution.
//
// * The name Colin Granville may not be used to endorse or promote
// products derived from this software without specific prior
// written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//
//--------------------------------------------------------------------------
#include "GuiDrawFile.h"
#include <string.h>
#include <limits.h>
#include "GuiDrawFileRender.h"
#include "iostream.h"
class GuiDrawFileHeader
{
public:
GuiDrawFileHeader(const char* progIdentity);
int draw;
int majorFormatVersion;
int minorFormatVersion;
char programIdentity[12];
GuiBBox bounds;
};
GuiDrawFileHeader::GuiDrawFileHeader(const char* progIdentity)
: draw(*((int*)"Draw")),
majorFormatVersion(201),
minorFormatVersion(0)
{
strncpy(programIdentity, progIdentity,11);
programIdentity[11]=0;
}
//***************************************************************
//***************************************************************
//***************************************************************
GuiDrawFile::GuiDrawFile(const char* progName)
: programName(progName)
{
reopen();
}
//***************************************************************
GuiDrawFile::~GuiDrawFile()
{
}
//***************************************************************
inline void GuiDrawFile::setBBox() {((GuiDrawFileHeader*)getPtr(0))->bounds=bounds;}
inline void GuiDrawFile::setBBox() const {((GuiDrawFileHeader*)getPtr(0))->bounds=bounds;}
//***************************************************************
void GuiDrawFile::reopen()
{
size=0;
capacity=0;
currentObject=npos;
failed=0;
data.clear();
int pos=allocate(sizeof(GuiDrawFileHeader));
if (failed) {failed |= FILE_FAILED;return;}
GuiDrawFileHeader header(programName.c_str());
*((GuiDrawFileHeader*)getPtr(pos))=header;
bounds(INT_MAX,INT_MAX,INT_MIN,INT_MIN);
}
//***************************************************************
_kernel_oserror* GuiDrawFile::save(const char* filename)
{
if (failed & FILE_FAILED) return 0;
setBBox();
return _swix(OS_File,_INR(0,5),10,filename,0xAff,0,getPtr(0),getPtr(size));
}
//***************************************************************
_kernel_oserror* GuiDrawFile::render(const GuiTransform* trans, const GuiBBox* clip, bool toPrinter) const
{
if (failed & FILE_FAILED) return 0;
setBBox();
return GuiDrawFile_render(*this,(DrawFileVisitor::Transform*)trans,clip,toPrinter);
}
//***************************************************************
_kernel_oserror* GuiDrawFile::getBBox(GuiBBox& bounds,const GuiTransform* trans) const
{
if (failed & FILE_FAILED) return 0;
setBBox();
//GuiDrawFile_BBox
return _swix(0x45541,_INR(0,4),0,getPtr(0),size,trans,&bounds);
}
//***************************************************************
_kernel_oserror* GuiDrawFile::declareFonts(bool dont_download) const
{
if (failed & FILE_FAILED) return 0;
setBBox();
//GuiDrawFile_DeclareFonts
return _swix(0x45542,_INR(0,2),(dont_download ? 1:0) ,getPtr(0),size);
}
//***************************************************************
void GuiDrawFile::ensureMem(unsigned int size)
{
//make sure there will be 64k free after allocation
if (gflex()->availableMemory() < size+64*1024) failed |= OBJECT_FAILED;
// size+=(64*1024);
// unsigned int oldSize=0;
// unsigned int newSize=0;
// _kernel_oserror* err=_swix(Wimp_SlotSize,_INR(0,1) |_OUT(0),-1,-1,&oldSize);
// if (!err) err= _swix(Wimp_SlotSize,_INR(0,1) |_OUT(0),oldSize+size,-1,&newSize);
// if (!err) _swix(Wimp_SlotSize,_INR(0,1),oldSize,-1);
// if (err || newSize-oldSize < size) failed |= OBJECT_FAILED;
}
//***************************************************************
size_t GuiDrawFile::allocate(size_t block_size)
{
if (failed) return npos;
if (size+block_size>capacity)
{
//add 4k buffer
int newsize=((block_size+3)&~3)+4*1024;
ensureMem(newsize);
if (hasFailed()) return npos;
if (!data.extend(size+newsize))
{
failed |= OBJECT_FAILED;
return npos;
}
capacity=data.size();
}
if (size+block_size<=capacity)
{
int old_size=size;
size+=block_size;
return old_size;
}
failed |= OBJECT_FAILED;
return npos;
}
//***************************************************************
bool GuiDrawFile::extend(size_t block_size)
{
if (failed) return 0;
size_t old_capacity=capacity;
//add 4k buffer
int newsize=((block_size+3)&~3)+4*1024;
ensureMem(newsize);
if (hasFailed() || !data.extend(capacity+newsize))
{
failed |= OBJECT_FAILED;
if (currentObject!=npos)
{
data.resize(currentObject);
capacity=data.size();
size=capacity;
return 0;
}
}
capacity=data.size();
return capacity>=old_capacity+block_size;
}
//***************************************************************
size_t GuiDrawFile::startObject(size_t s)
{
endCurrentObject();
align();
currentObject=allocate(s);
if (currentObject==npos) currentObject=size;
return currentObject;
}
//***************************************************************
void GuiDrawFile::endObject()
{
if (!failed) currentObject=npos;
}
//***************************************************************
void GuiDrawFile::endCurrentObject()
{
if (currentObject!=npos) size=currentObject;
failed &= ~OBJECT_FAILED;
currentObject=npos;
}